home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / inventor / soundspheres / main.c++ < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  8.1 KB  |  304 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. // sound spheres, a program demonstrating Inventor 2.0 and the Audio Library
  18. // written by Kevin Goldsmith at SGI - spring '94
  19.  
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <malloc.h>
  23. #include <math.h>
  24. #include <getopt.h>
  25. #include <unistd.h>
  26. #include <sys/time.h>
  27. #include <Inventor/Xt/SoXt.h>
  28. #include <Inventor/Xt/viewers/SoXtPlaneViewer.h>
  29. #include <Inventor/nodes/SoSphere.h>
  30. #include <Inventor/nodes/SoSeparator.h>
  31. #include <Inventor/nodes/SoTransform.h>
  32. #include <Inventor/nodes/SoMaterial.h>
  33. #include <Inventor/sensors/SoFieldSensor.h>
  34. #include <Inventor/draggers/SoDragPointDragger.h>
  35. #include <Inventor/engines/SoCalculator.h>
  36.  
  37. #include "PlayClass.h"
  38.  
  39. /*
  40.  * local defines
  41.  */
  42.  
  43. #ifndef FALSE
  44. #define FALSE (0)
  45. #define TRUE (!FALSE)
  46. #endif
  47. #ifndef ABS
  48. #define ABS(a)        ((a)>0.0?(a):-(a))
  49. #endif
  50. #ifndef MIN
  51. #define    MIN(a, b)    ((a)<(b)?(a):(b))
  52. #endif
  53. #ifndef MAX
  54. #define    MAX(a, b)    ((a)>(b)?(a):(b))
  55. #endif
  56. #define    RANGE(a, b1, b2)            \
  57.                         \
  58.         ((b1)<(b2)?                \
  59.          ((a)<(b1)?                \
  60.           (b1):                \
  61.           ((a)>(b2)?            \
  62.                (b2):(a))):        \
  63.          ((a)<(b2)?                \
  64.           (b2):                \
  65.           ((a)>(b1)?            \
  66.                (b1):(a))))
  67.  
  68. #ifndef INTERP
  69. #define INTERP(x1, x2, a) ((a)*(x2)+(1.0-(a))*(x1))
  70. #endif
  71.  
  72. double xpos, ypos, ipos, jpos;
  73. char *filename[4];
  74. int num = 0;
  75.  
  76. typedef struct {
  77.     PlayClass *pc;
  78.     SoTransform *trans;
  79. } CBstruct;
  80.  
  81. typedef struct {
  82.     PlayClass *pc[4];
  83.     int num;
  84.     SoTransform *trans;
  85. } CBstruct2;
  86.  
  87.  
  88. static void
  89. emitCB(void *userData, SoSensor *)
  90. {
  91.  
  92.   CBstruct *cbs = (CBstruct *) userData;
  93.   cbs->pc->setEmitterPosition((cbs->trans->translation.getValue()[0]), 
  94.                   (cbs->trans->translation.getValue()[1]),
  95.                   (cbs->trans->translation.getValue()[2]));
  96. }
  97.  
  98. static void
  99. recCB(void *userData, SoSensor *)
  100. {
  101.  
  102.   CBstruct2 *cbs = (CBstruct2 *) userData;
  103.   for (int i = 0; i < cbs->num; i++) {
  104.      cbs->pc[i]->setReceiverPosition((cbs->trans->translation.getValue()[0]), 
  105.                      (cbs->trans->translation.getValue()[1]),
  106.                      (cbs->trans->translation.getValue()[2]));
  107.   }
  108. }
  109.  
  110. static void
  111. parseCommandLine(int argc, char **argv)
  112. {
  113.     int err = 0;    // Flag: error in options?
  114.     int c;
  115.  
  116.     while (( c = getopt(argc, argv, "")) != -1)
  117.       {
  118.       switch(c)
  119.         {
  120.           default:
  121.         err = 1;
  122.         break;
  123.         }
  124.       
  125.       }
  126.  
  127.  
  128.     if (optind == argc) err = 1;
  129.  
  130.     else {
  131.     if (argc > optind ) 
  132.         filename[num++] = argv[optind];
  133.     if (argc > optind + 1)
  134.         filename[num++] = argv[optind + 1];
  135.     if (argc > optind + 2)
  136.         filename[num++] = argv[optind + 2];
  137.     if (argc > optind + 3)
  138.         filename[num++] = argv[optind + 3];
  139.     }
  140.  
  141.     if (err)
  142.     {
  143.     fprintf(stderr,
  144.         "Usage: %s filename1 [filename2] [filename3] [filename4]\n",
  145.         argv[0]);
  146.     exit(99);
  147.     }
  148. }
  149.  
  150. main(int argc, char **argv)
  151. {
  152.     PlayClass *pc[4];
  153.     int i;
  154.  
  155.     ipos = jpos = xpos = ypos = 0.0;
  156.     for (i = 0; i < 4; i++) filename[i] = NULL;
  157.  
  158.     parseCommandLine(argc,argv);
  159.  
  160.     for (i = 0; i < num; i++) {
  161.         pc[i] = new PlayClass(argv[0]);
  162.  
  163.         pc[i]->setFilename(filename[i]);
  164.         pc[i]->setUseDistance(TRUE);
  165.         pc[i]->setLoop(TRUE);
  166.     }
  167.  
  168.     // Initialize Inventor. This will return a main window to use.
  169.     // If unsuccessful, exit.
  170.     Widget appWindow = SoXt::init(argv[0]); // pass the app name
  171.     if ( appWindow == NULL ) exit( 1 );
  172.  
  173.     // create the top level separators
  174.     SoSeparator *root = new SoSeparator;
  175.     root->ref();
  176.  
  177.     SoSeparator *draggerSep = new SoSeparator;
  178.     root->addChild(draggerSep);
  179.  
  180.     // create the transform that will make the draggers larger
  181.     SoTransform *draggerTrans = new SoTransform;
  182.     draggerTrans->scaleFactor.setValue(2.0, 2.0, 2.0);
  183.     draggerSep->addChild(draggerTrans);
  184.  
  185.     // create the nodes needed for the emitters
  186.     SoSeparator *emitSep[4];
  187.     SoTransform *emitTrans[4];
  188.     SoMaterial  *emitMat[4];
  189.     SoSphere    *emitSph[4];
  190.     SoDragPointDragger *emitDragger[4];
  191.     SoCalculator *emitCalc[4];
  192.  
  193.     // create and initalize the emitters
  194.     for (i = 0; i < num; i++) {
  195.     emitSep[i] = new SoSeparator;
  196.     emitTrans[i] = new SoTransform;
  197.     emitMat[i] = new SoMaterial;
  198.     emitDragger[i] = new SoDragPointDragger;
  199.     emitCalc[i] = new SoCalculator;
  200.     emitCalc[i]->ref();
  201.  
  202.     // initialize the location and color of the emitter
  203.     switch (i) {
  204.             case 0:
  205.             emitDragger[i]->translation.setValue( - 5.0, 0.0, - 5.0);
  206.             emitMat[i]->diffuseColor.setValue(1.0,0.0,0.0);
  207.             break;
  208.         case 1:
  209.             emitDragger[i]->translation.setValue(5.0, 0.0, 5.0);
  210.             emitMat[i]->diffuseColor.setValue(0.0,1.0,0.0);
  211.             break;
  212.         case 2:
  213.             emitDragger[i]->translation.setValue(- 5.0, 0.0, 5.0);
  214.                 emitMat[i]->diffuseColor.setValue(0.0,0.0,1.0);
  215.             break;
  216.         case 3:
  217.             emitDragger[i]->translation.setValue(5.0, 0.0, - 5.0);
  218.                 emitMat[i]->diffuseColor.setValue(1.0,0.0,1.0);
  219.             break;
  220.         default:
  221.             emitDragger[i]->translation.setValue(0.0, 0.0, 0.0);
  222.             emitMat[i]->diffuseColor.setValue(1.0,1.0,1.0);
  223.             break;
  224.         }
  225.  
  226.     // add the new nodes to the scene
  227.     emitSep[i]->addChild(emitTrans[i]);
  228.         emitSep[i]->addChild(emitMat[i]);
  229.         emitSph[i] = new SoSphere;
  230.         emitSep[i]->addChild(emitSph[i]);
  231.     root->addChild(emitSep[i]);
  232.     draggerSep->addChild(emitDragger[i]);
  233.  
  234.     // create a calculator to counteract the scale affecting the draggers
  235.     emitCalc[i]->A.connectFrom(&emitDragger[i]->translation);
  236.     emitCalc[i]->B.connectFrom(&draggerTrans->scaleFactor);
  237.     emitCalc[i]->expression= "oA = vec3f(A[0]*B[0], A[1]*B[1], A[2]*B[2])";
  238.  
  239.     // connect the translation of the emitter to the output of the calc
  240.     emitTrans[i]->translation.connectFrom(&emitCalc[i]->oA);
  241.  
  242.     CBstruct *cbs = new CBstruct;
  243.     cbs->pc = pc[i];
  244.     cbs->trans = emitTrans[i];
  245.  
  246.     // create a sensor that will notify us when the translation changes
  247.     // so that we can update the audio
  248.     SoFieldSensor *emitSens = new SoFieldSensor(emitCB, cbs);
  249.     emitSens->attach(&emitTrans[i]->translation);
  250.     }
  251.  
  252.  
  253.     // create the receiver nodes
  254.     SoSeparator *recSep = new SoSeparator;
  255.     SoTransform *recTrans = new SoTransform;
  256.     recSep->addChild(recTrans);
  257.     SoMaterial *recMat = new SoMaterial;
  258.     recSep->addChild(recMat);
  259.     SoSphere *recSph = new SoSphere;
  260.     recSep->addChild(recSph);
  261.     root->addChild(recSep);
  262.  
  263.     // create the dragger and calculator used by the receiver
  264.     SoDragPointDragger *recDragger = new SoDragPointDragger();
  265.     SoCalculator *recCalc = new SoCalculator;
  266.     recCalc->ref();
  267.     recCalc->A.connectFrom(&recDragger->translation);
  268.     recCalc->B.connectFrom(&draggerTrans->scaleFactor);
  269.     recCalc->expression = "oA = vec3f(A[0]*B[0], A[1]*B[1], A[2]*B[2])";
  270.  
  271.     recTrans->translation.connectFrom(&recCalc->oA);
  272.     draggerSep->addChild(recDragger);
  273.  
  274.     CBstruct2 *cbs3 = new CBstruct2;
  275.     cbs3->num = num;
  276.     for (i = 0; i < num; i++) cbs3->pc[i] = pc[i];
  277.     cbs3->trans = recTrans;
  278.  
  279.     SoFieldSensor *recSens = new SoFieldSensor(recCB, cbs3);
  280.     recSens->attach(&recTrans->translation);
  281.  
  282.  
  283.     // set up the play classes so that they have the correct locations of
  284.     // the emitter and receiver
  285.     for (i = 0; i < num; i++) {
  286.     pc[i]->setEmitterPosition((emitTrans[i]->translation.getValue())[0],
  287.                   (emitTrans[i]->translation.getValue())[1],
  288.                   (emitTrans[i]->translation.getValue())[2]);
  289.     pc[i]->setReceiverPosition((recTrans->translation.getValue())[0],
  290.                    (recTrans->translation.getValue())[1],
  291.                    (recTrans->translation.getValue())[2]);
  292.     pc[i]->start();  // begin the audio
  293.     }
  294.  
  295.     SoXtPlaneViewer *viewer = new SoXtPlaneViewer(appWindow);
  296.     viewer->setSceneGraph(root);
  297.     viewer->show();
  298.  
  299.     SoXt::show(appWindow);
  300.     SoXt::mainLoop();
  301.  
  302.     while(TRUE) {}
  303. }
  304.